package com.ailight.smart.ai.config;

import cn.hutool.json.JSONUtil;
import com.ailight.smart.ai.enums.AiModelEnum;
import com.ailight.smart.ai.enums.OperationTypeEnums;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.*;

@Configuration
@RequiredArgsConstructor
public class DeepSeekConfig {
    @Value("${spring.ai.openai.api-key}")
    private String apiKey;

    @Value("${spring.ai.openai.base-url}")
    private String baseUrl;

    private final ObjectMapper objectMapper;

    private final List<FunctionCallback> functionCallbacks;

    @Bean
    public OpenAiApi openAiApi() {
        return new OpenAiApi(baseUrl, apiKey);
    }

    @Bean
    public OpenAiChatClient openAiChatClient(OpenAiApi openAiApi) throws JsonProcessingException {
        // 将 FunctionCallback 转换为 DeepSeek 需要的工具格式
        List<OpenAiApi.FunctionTool> tools = convertFunctionCallbacksToTools(functionCallbacks);
        System.out.println("222:" + JSONUtil.toJsonStr(tools));
        OpenAiChatOptions options = OpenAiChatOptions.builder()
                .withModel(AiModelEnum.DEEP_SEEK_CHAT.getModelName())
                .withTemperature(0.7f)
                .withMaxTokens(2000)
                .withTopP(0.9f)
                .withTools(tools)
                .withFunctionCallbacks(functionCallbacks)
                .withToolChoice("auto") // 让模型自动选择工具
                .build();
        System.out.println("111:" + objectMapper.writeValueAsString(options));
        return new OpenAiChatClient(openAiApi, options);
    }

    /**
     * 将 FunctionCallback 转换为 DeepSeek 需要的工具格式
     */
    private List<OpenAiApi.FunctionTool> convertFunctionCallbacksToTools(List<FunctionCallback> functionCallbacks) {
        List<OpenAiApi.FunctionTool> tools = new ArrayList<>();

        for (FunctionCallback callback : functionCallbacks) {
            OpenAiApi.FunctionTool functionTool = new OpenAiApi.FunctionTool(
                    OpenAiApi.FunctionTool.Type.FUNCTION,
                    new OpenAiApi.FunctionTool.Function(
                            callback.getDescription(),
                            callback.getName(),
                            createParametersSchema(callback)
                    )
            );
            tools.add(functionTool);
        }

        return tools;
    }

    /**
     * 创建函数参数的模式定义
     */
    private Map<String, Object> createParametersSchema(FunctionCallback callback) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("type", "object");

        Map<String, Object> properties = new HashMap<>();
        List<String> required = new ArrayList<>();

        // 这里简化处理，实际应根据 FunctionCallback 的输入类型创建详细的参数模式
        // 对于天气查询函数
        if ("getWeather".equals(callback.getName())) {
            properties.put("city", Map.of(
                    "type", "string",
                    "description", "城市名称"
            ));
            required.add("city");
        }
        // 对于计算器函数
        if ("calculate".equals(callback.getName())) {
            properties.put("a", Map.of(
                    "type", "number",
                    "description", "第一个数字"
            ));
            properties.put("b", Map.of(
                    "type", "number",
                    "description", "第二个数字"
            ));
            properties.put("operation", Map.of(
                    "type", "string",
                    "description", "运算类型: add, subtract, multiply, divide",
                    "enum", Arrays.asList("add", "subtract", "multiply", "divide")
            ));
            required.addAll(Arrays.asList("a", "b", "operation"));
        }
         // 对于远程控制智能灯关闭函数
         if ("lightControl".equals(callback.getName())) {
             properties.put("modelName", Map.of(
                     "type", "string",
                     "description", "直接控制智能灯具的操作指令，必须从以下选项中选择：" +
                             "turn_light(开灯), manual_off(关灯), " +
                             "auto_mode(自动模式), manual_mode(手动模式), " +
                             "gear_one(一档)，gear_two(二档)，gear_three(三档)" +
                             "只需根据用户需求选择对应的操作，无需考虑当前灯具状态",
                     "enum", OperationTypeEnums.getOperationTypeNames()
             ));
            required.add("optName");
        }
        parameters.put("properties", properties);
        parameters.put("required", required);
        return parameters;
    }
}
